home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HPAVC
/
HPAVC CD-ROM.iso
/
TASMSWAN.ZIP
/
ASYNCH.ASM
< prev
next >
Wrap
Assembly Source File
|
1989-07-17
|
7KB
|
287 lines
%TITLE "Asynchronous Serial Communications Module"
IDEAL
DOSSEG
MODEL small
PUBLIC ComPort
ComPort = 0
IF ComPort EQ 0
Port EQU 03F8h
VectorNum EQU 0Ch
EnableIRQ EQU 0EFh
DisableIRQ EQU 10h
ELSEIF ComPort EQ 1
Port EQU 02F8h
VectorNum EQU 0Bh
EnableIRQ EQU 0F7h
DisableIRQ EQU 08h
ELSE
%DISPLAY "ComPort must be 0 or 1"
ERR
ENDIF
TxRegister = Port + 0
RxRegister = Port + 0
IntEnable = Port + 1
IntIdent = Port + 2
LineControl = Port + 3
ModemControl = Port + 4
LineStatus = Port + 5
ModemStatus = Port + 6
Ctrl8259_0 EQU 020h
Ctrl8259_1 EQU 021h
EOI EQU 020h
BufSize EQU 2048
DATASEG
vectorSeg dw ?
vectorOfs dw ?
bufHead dw ?
bufTail dw ?
buffer db BufSize DUP (?)
CODESEG
PUBLIC AsynchInit, AsynchStop, AsynchStat
PUBLIC AsynchOut, AsynchIn, AsynchInStat
%NEWPAGE
;------------------------------------------------------------------------
; EmptyBuffer - empty the input buffer
;------------------------------------------------------------------------
; NOTE: private to module
; Input: none
; Output: none
; Registers: none
;------------------------------------------------------------------------
PROC EmptyBuffer
cli
push ax
mov ax, offset buffer
mov [bufHead], ax
mov [bufTail], ax
pop ax
sti
ret
ENDP EmptyBuffer
%NEWPAGE
;------------------------------------------------------------------------
; AsynchInit - initialize serial port and install ISR
;------------------------------------------------------------------------
; Input: none
; Output: none
; NOTE: precede (usually) with call to int 14h
; to set baud rate
; NOTE: interrupt-driven input begins immediately
; upon exit from this routine
; WARNING: you MUST call AsynchStop before your program ends
; to avoid a !!! SYSTEM CRASH !!!
; Registers: ax,bx,dx
;------------------------------------------------------------------------
PROC AsynchInit
call EmptyBuffer
push ds
push es
mov ax, 3500h + VectorNum
int 21h
mov [vectorSeg], es
mov [vectorOfs], bx
push cs
pop ds
mov ds, offset AsynchISR
mov ax, 2500h + VectorNum
int 21h
pop es
pop ds
in al, Ctrl8259_1
and al, EnableIRQ
out Ctrl8259_1,al
mov dx,LineControl
in al,dx
and al,07Fh
out dx,al
mov dx,IntEnable
mov al,1
out dx,al
@@10:
mov dx,RxRegister
in al,dx
mov dx,LineStatus
in al,dx
mov dx,ModemStatus
in al,dx
mov dx,IntIdent
in al,dx
test al,1
jz @@10
mov dx,ModemControl
in al,dx
or al,08h
out dx,al
call EmptyBuffer
ret
ENDP AsynchInit
%NEWPAGE
;------------------------------------------------------------------------
; AsynchStop - uninstall asynch ISR
;------------------------------------------------------------------------
; Input: none
; Output: none
; WARNING: you MUST call AsynchStop before your program ends
; to avoid a !!! SYSTEM CRASH !!!
; Registers: al,dx
;------------------------------------------------------------------------
PROC AsynchStop
in al, Ctrl8259_1
or al, DisableIRQ
out Ctrl8259_1,al
mov dx,LineControl
in al,dx
and al,07Fh
out dx,al
mov dx, IntEnable
xor al,al
out dx,al
mov dx,ModemControl
in al,dx
and al, 0F7h
out dx,al
push ds
mov ax, 2500h + VectorNum
mov dx, [vectorOfs]
mov ds,[vectorSeg]
int 21h
pop ds
ret
ENDP AsynchStop
%NEWPAGE
;------------------------------------------------------------------------
; AsynchStat - get status for output
;------------------------------------------------------------------------
; Input: none
; Output: ah = line status, al = modem status
; Registers: ax,dx
;------------------------------------------------------------------------
PROC AsynchStat
mov ah,3
mov dx, ComPort
int 14h
ret
ENDP AsynchStat
%NEWPAGE
;------------------------------------------------------------------------
; AsynchOut - output a byte (to the output port)
;------------------------------------------------------------------------
; Input: al = character (or byte) to output
; Output: none
; Registers: none
;------------------------------------------------------------------------
PROC AsynchOut
push dx
push ax
@@10:
mov dx, LineStatus
in al,dx
and al,020h
jz @@10
pop ax
mov dx, TxRegister
out dx,al
pop dx
ret
ENDP AsynchOut
%NEWPAGE
;------------------------------------------------------------------------
; AsynchIn - input a byte (from buffer)
;------------------------------------------------------------------------
; Input: none
; Output: al = char from buffer
; NOTE: if buffer is empty, al will be 0, with
; no indication that this is not an input value.
; Precede with call to AsynchInStat to avoid reads
; from an empty buffer.
; Registers: al,bx
;------------------------------------------------------------------------
PROC AsynchIn
xor al,al
mov bx,[bufTail]
cmp bx,[bufHead]
je @@99
mov al,[byte ptr bx]
inc [bufTail]
cmp [word ptr bufTail], offset buffer + BufSize
jb @@99
mov [bufTail], offset buffer
@@99:
ret
ENDP AsynchIn
%NEWPAGE
;------------------------------------------------------------------------
; AsynchInStat - get status of input buffer
;------------------------------------------------------------------------
; Input: none
; Output: dx = number of bytes (or chars) in buffer
; Registers: dx
;------------------------------------------------------------------------
PROC AsynchInStat
mov dx,[bufHead]
sub dx,[bufTail]
jge @@99
add dx,BufSize
@@99:
ret
ENDP AsynchInStat
%NEWPAGE
;------------------------------------------------------------------------
; AsynchISR - asynchronous input Interrupt Service Routine (ISR)
;------------------------------------------------------------------------
; Input: none
; Output: none (char read and deposited in buffer)
; NOTE: this version ignores buffer overflows
; Registers: none
;------------------------------------------------------------------------
PROC AsynchISR
push ax
push bx
push ds
push dx
mov ax,@data
mov ds,ax
mov dx,RxRegister
in al,dx
mov bx,[bufHead]
mov [byte ptr bx], al
inc bx
cmp bx,offset buffer + BufSize
jb @@10
mov bx, offset buffer
@@10:
cmp bx,[bufTail]
jne @@20
mov bx,[bufHead]
@@20:
mov [bufHead],bx
mov al,EOI
out Ctrl8259_0,al
pop dx
pop ds
pop bx
pop ax
iret
ENDP AsynchISR
END